﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace Sped.Sped
{
    /// <summary>
    /// REGISTRO C100: DOCUMENTO - NOTA FISCAL (CÓDIGO 01), NOTA FISCAL AVULSA
    /// (CÓDIGO 1B), NOTA FISCAL DE PRODUTOR (CÓDIGO 04) e NF-e (CÓDIGO 55)
    /// </summary>
    [ClassInterface(ClassInterfaceType.AutoDual)]
    [ProgId("SpedPisCofins.RegC100")]
    [ComVisible(true)]
    public class RegC100 : IBloco
    {
        /// <summary>
        /// Indicador do tipo de operação:
        ///     0 - Serviço Contratado pelo Estabelecimento;
        ///     1 - Serviço Prestado pelo Estabelecimento.
        /// </summary>
        public string IND_OPER { get; set; }
        /// <summary>
        /// Indicador do emitente do documento fiscal:
        ///     0 - Emissão própria;
        ///     1 - Emissão de Terceiros
        /// </summary>
        public string IND_EMIT { get; set; }
        /// <summary>
        /// Código do participante (campo 02 do Registro 0150):
        ///     - do emitente do documento, no caso de emissão de terceiros;
        ///     - do adquirente, no caso de serviços prestados.
        /// </summary>
        public string COD_PART { get; set; }
        /// <summary>
        /// Código do modelo do documento fiscal, conforme a Tabela 4.1.1
        /// </summary>
        public string COD_MOD { get; set; }
        /// <summary>
        /// Código da situação do documento fiscal:
        ///     00 – Documento regular
        ///     02 – Documento cancelado
        /// </summary>
        public string COD_SIT { get; set; }
        /// <summary>
        /// Série do documento fiscal
        /// </summary>
        public string SER { get; set; }
        /// <summary>
        /// Número do documento fiscal ou documento internacional equivalente
        /// </summary>
        public string NUM_DOC { get; set; }
        /// <summary>
        /// Chave da Nota Fiscal Eletrônica
        /// </summary>
        public string CHV_NFE { get; set; }
        /// <summary>
        /// Data da emissão do documento fiscal
        /// </summary>
        public DateTime DT_DOC { get; set; }
        /// <summary>
        /// Data da entrada ou da saída
        /// </summary>
        public DateTime DT_E_S { get; set; }
        /// <summary>
        /// Valor total do documento
        /// </summary>
        public double VL_DOC { get; set; }
        /// <summary>
        /// Indicador do tipo de pagamento:
        ///     0- À vista;
        ///     1- A prazo;
        ///     9- Sem pagamento
        /// </summary>
        public string IND_PGTO { get; set; }
        /// <summary>
        /// Valor total do desconto
        /// </summary>
        public double VL_DESC { get; set; }
        /// <summary>
        /// Abatimento não tributado e não comercial Ex. desconto ICMS nas remessas para ZFM.
        /// </summary>
        public double VL_ABAT_NT { get; set; }
        /// <summary>
        /// Valor total das mercadorias e serviços
        /// </summary>
        public double VL_MERC { get; set; }
        /// <summary>
        /// Indicador do tipo do frete:
        ///     0- Por conta de terceiros;
        ///     1- Por conta do emitente;
        ///     2- Por conta do destinatário;
        ///     9- Sem cobrança de frete.
        /// </summary>
        public string IND_FRT { get; set; }
        /// <summary>
        /// Valor do frete indicado no documento fiscal
        /// </summary>
        public double VL_FRT { get; set; }
        /// <summary>
        /// Valor do seguro indicado no documento fiscal
        /// </summary>
        public double VL_SEG { get; set; }
        /// <summary>
        /// Valor de outras despesas acessórias
        /// </summary>
        public double VL_OUT_DA { get; set; }
        /// <summary>
        /// Valor da base de cálculo do ICMS
        /// </summary>
        public double VL_BC_ICMS { get; set; }
        /// <summary>
        /// Valor do ICMS
        /// </summary>
        public double VL_ICMS { get; set; }
        /// <summary>
        /// Valor da base de cálculo do ICMS substituição tributária
        /// </summary>
        public double VL_BC_ICMS_ST { get; set; }
        /// <summary>
        /// Valor do ICMS retido por substituição tributária
        /// </summary>
        public double VL_ICMS_ST { get; set; }
        /// <summary>
        /// Valor total do IPI
        /// </summary>
        public double VL_IPI { get; set; }
        /// <summary>
        /// Valor total do PIS
        /// </summary>
        public double VL_PIS { get; set; }
        /// <summary>
        /// Valor total da COFINS
        /// </summary>
        public double VL_COFINS { get; set; }
        /// <summary>
        /// Valor total do PIS retido por substituição tributária
        /// </summary>
        public double VL_PIS_ST { get; set; }
        /// <summary>
        /// Valor total da COFINS retido por substituição tributária
        /// </summary>
        public double VL_COFINS_ST { get; set; }



        public override bool ValidaRegistro(ref string Erro)
        {
            var ValidacaoOK = true;
            Erro = "";

            if (string.IsNullOrEmpty(this.IND_OPER))
                this.IND_OPER = string.Empty;
            if (!this.IND_OPER.StringIN("0-1"))
            {
                Erro += "\r\n* Registro C100 - Indicador do tipo de operação inválido.";
                ValidacaoOK = false;
            }
           
            if (string.IsNullOrEmpty(this.IND_EMIT))
                this.IND_EMIT = string.Empty;
            if (!this.IND_EMIT.StringIN("0-1"))
            {
                Erro += "\r\n* Registro C100 - Indicador do emitente do documento fiscal inválido.";
                ValidacaoOK = false;
            }

            if (string.IsNullOrEmpty(this.COD_PART))
            {
                this.COD_PART = string.Empty;
                Erro += "\r\n* Registro C100 - Código do participante inválido.";
                ValidacaoOK = false;
            }

            if (string.IsNullOrEmpty(this.COD_MOD))
            {
                this.COD_MOD = string.Empty;
                Erro += "\r\n* Registro C100 - Código do modelo do documento fiscal inválido.";
                ValidacaoOK = false;
            }

            if (this.COD_MOD.StringIN("01-1B-04-55"))
            {
                Erro += "\r\n* Registro C100 - Código do modelo do documento fiscal inválido.";
                ValidacaoOK = false;
            }

            if (string.IsNullOrEmpty(this.COD_SIT))
            {
                this.COD_SIT = string.Empty;
                Erro += "\r\n* Registro C100 - Código da situação do documento fiscal inválido.";
                ValidacaoOK = false;
            }

            if (string.IsNullOrEmpty(this.SER))
                this.SER = string.Empty;

            if (string.IsNullOrEmpty(this.NUM_DOC))
            {
                this.NUM_DOC = string.Empty;
                Erro += "\r\n* Registro C100 - Número do documento fiscal inválido.";
                ValidacaoOK = false;
            }

            if (string.IsNullOrEmpty(this.CHV_NFE) && this.COD_MOD == "55" && this.IND_OPER == "0")
            {
                Erro += "\r\n* Registro C100 - Obrigatório Chave da NF-e, COD_MOD igual a “55”, de emissão própria.";
                ValidacaoOK = false;
            }

            if (!this.IND_PGTO.StringIN("0-1-9"))
            {
                Erro += "\r\n* Registro C100 - Indicador do tipo de pagamento inválido.";
                ValidacaoOK = false;
            }

            if (!this.IND_FRT.StringIN("0-1-2-9"))
            {
                Erro += "\r\n* Registro C100 - Indicador do tipo de Frete inválido.";
                ValidacaoOK = false;
            }

            return ValidacaoOK;
        }

        public override string Layout()
        {
            var Linha = string.Empty;

            Linha += "C100" + this.Delimitador;
            Linha += this.IND_OPER.Trim() + this.Delimitador;
            Linha += this.IND_EMIT.Trim() + this.Delimitador;
            Linha += this.COD_PART.Trim() + this.Delimitador;
            Linha += this.COD_SIT.Trim() + this.Delimitador;
            Linha += this.COD_MOD.Trim() + this.Delimitador;
            Linha += this.SER.Trim() + this.Delimitador;
            Linha += this.NUM_DOC.Trim() + this.Delimitador;
            Linha += this.CHV_NFE.Trim() + this.Delimitador;
            Linha += this.DT_DOC.FormatoDataSped() + this.Delimitador;
            Linha += this.DT_E_S.FormatoDataSped() + this.Delimitador;
            Linha += this.VL_DOC.FormatoValorSped(2).Trim() + this.Delimitador;
            Linha += this.IND_PGTO.Trim() + this.Delimitador;
            Linha += this.VL_DESC.FormatoValorSped(2) + this.Delimitador;
            Linha += this.VL_ABAT_NT.FormatoValorSped(2) + this.Delimitador;
            Linha += this.VL_MERC.FormatoValorSped(2) + this.Delimitador;
            Linha += this.IND_FRT.Trim() + this.Delimitador;
            Linha += this.VL_FRT.FormatoValorSped(2) + this.Delimitador;
            Linha += this.VL_SEG.FormatoValorSped(2) + this.Delimitador;
            Linha += this.VL_OUT_DA.FormatoValorSped(2) + this.Delimitador;
            Linha += this.VL_BC_ICMS.FormatoValorSped(2) + this.Delimitador;
            Linha += this.VL_ICMS.FormatoValorSped(2) + this.Delimitador;
            Linha += this.VL_BC_ICMS_ST.FormatoValorSped(2) + this.Delimitador;
            Linha += this.VL_ICMS_ST.FormatoValorSped(2) + this.Delimitador;
            Linha += this.VL_IPI.FormatoValorSped(2) + this.Delimitador;
            Linha += this.VL_PIS.FormatoValorSped(2) + this.Delimitador;
            Linha += this.VL_COFINS.FormatoValorSped(2) + this.Delimitador;
            Linha += this.VL_PIS_ST.FormatoValorSped(2) + this.Delimitador;
            Linha += this.VL_COFINS_ST.FormatoValorSped(2) + this.Delimitador;

            return Linha.Trim();
        }
    }
}
